<template>
  <div class="login-page">
    <el-card class="login-card">
      <!-- slot="header" 具名插槽的旧语法, 现已被淘汰 -->
      <template #header>
        <h3>黑马面经运营后台</h3>
      </template>
      <!--
        element 表单校验检查清单:
          1. el-form: model (数据对象) 和 rules (规则对象)
          2. el-form-item: prop 设置字符串 (指定用哪个规则)
          3. 表单元素 v-model 绑定数据
       -->
      <el-form ref="form" :model="form" :rules="rules">
        <!-- form-item 表示一个表单数据, 一项表单数据也被称为一个字段 (field) -->
        <el-form-item prop="username" label="用户名">
          <el-input placeholder="请输入用户名" v-model="form.username"></el-input>
        </el-form-item>
        <el-form-item prop="password" label="密码">
          <el-input placeholder="请输入密码" type="password" v-model="form.password"></el-input>
        </el-form-item>
        <el-form-item class="tc">
          <el-button type="primary" @click="onSubmit">登 录</el-button>
          <el-button @click="$refs.form.resetFields()">重 置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script>
export default {
  name: 'LoginIndex',
  data () {
    return {
      form: {
        username: '',
        password: ''
      },
      rules: {
        // rules 是校验规则
        // 一个属性表示一个字段的校验规则
        // 而一个字段的校验规则可以有很多个, 所以定义成数组
        username: [
          // required: 表示必填
          // message: 提示的文字信息
          // trigger: 触发校验的时机 (blur 失去焦点, change 输入时), 用数组可以同时支持多种时机校验
          // min: 最少多少位字符
          // max: 多大多少位字符
          // pattern: 正则校验
          { required: true, message: '请输入用户名', trigger: ['blur', 'change'] },
          { pattern: /^\w{5,10}$/, message: '长度在 5 到 10 个字符', trigger: ['blur', 'change'] }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { min: 5, max: 10, message: '长度在 5 到 10 个字符', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    onSubmit () {
      // 发送请求前的兜底校验
      // 表单对象.validate 可以对整个表单进行校验, 结果通过回调函数传入
      this.$refs.form.validate(async valid => {
        // console.log(valid)
        if (!valid) return // 不用提醒
        // console.log('我要去登录!')

        // await 必须要加, 表示等待登录完成拿到结果后再往后处理业务
        await this.$store.dispatch('user/loginAction', this.form)

        // 页面跳转, 去首页
        this.$router.push('/')

        // 提示用户登录成功
        this.$message.success('登录成功')
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.login-page {
  background-image: url('@/assets/login-bg.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100%;
  // 不建议使用 100% 太麻烦了, 因为 100% 相对的是父盒子的高度
  // 100vh 相当于是视口高度的 100%
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

// scoped 的作用: 让样式只应用在当前组件标签上
// 原理:
// 1. 给当前组件内所有标签添加一个自定义属性: data-v-hash (组件内的标签不会自动加上这个属性)
// 2. 给所有选择器加上一个属性交集选择器

// 会导致修改组件内标签样式失败, 解决方案:
// 1. 不加 scoped (风险高, 容易和其他组件样式冲突)
// 2. 深度作用选择器 (预处理器提供的, 所以不同的预处理器语法不同)
//   scss: ::v-deep
//   less: /deep/
.login-card {
  width: 430px;
  // 审查元素得到类名
  ::v-deep .el-card__header {
    background-color: #727cf5;
    height: 85px;
    line-height: 85px;
    padding: 0;
    h3 {
      margin: 0;
      color: white;
      text-align: center;
      font-weight: 400;
    }
  }
  .el-form {
    padding: 0 20px;
  }
  .tc {
    text-align: center
  }
}
</style>
